#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define ALG_FILE_NAME_MAX       30
#define ALG_BYTE                4

static int alg_byte_defalut = ALG_BYTE;

int algintobin(char *algfilename,char * sourcefile)
{
    off_t file_len;
    off_t alg_file_relen;
    int algfd,sourcefd;
    struct stat filestat;
    int len;
    char buff[4096];
    memset(buff,0,sizeof(buff));
    sourcefd=open(sourcefile,O_RDONLY);
    if(sourcefd==-1){
        printf("open sourcefd is error\n");
        return -1;
    }
    //获取文件长度
    if(fstat(sourcefd,&filestat)!=0){
        printf("fstat algfd is error\n");
        return -1;
    }
    file_len=filestat.st_size;
    printf("source file len is:%ld\n",file_len);
    //计算出对齐后的长度
    alg_file_relen=alg_byte_defalut-(file_len%alg_byte_defalut);

    //创建algfd文件
    algfd=open(algfilename,O_RDWR|O_CREAT,S_IRWXU);
    if(algfd==-1){
        close(sourcefd);
        printf("open algfilename is error\n");
        return -1;
    }
    //拷贝源文件额内容到对齐文件中
    while((len=read(sourcefd,buff,4096))!=0){
        if((int)(write(algfd,buff,len))!=len){
            printf("write error\n");
            close(algfd);
            close(sourcefd);
            return -1;
        }
    }
    //最后将剩余的字节书写如进入
    memset(buff,0xff,alg_file_relen);
    if((int)(write(algfd,buff,alg_file_relen))!=alg_file_relen){
        printf("write alg_file_relen error\n");
        close(algfd);
        close(sourcefd);
        return -1;
    }

    close(algfd);
    close(sourcefd);
    printf("alg file make is success,alg file total len:%ld\n",(alg_file_relen+file_len));
    return 0;   
}
/**
 * -b bootloader文件
 * -a app文件
 * -p 分区表文件
 * -f 出厂文件
 */ 
int main(int argc, char * argv[])
{
    int ch;
    char algfilename[ALG_FILE_NAME_MAX];
    char sourcefile[ALG_FILE_NAME_MAX];
    int tmp_alg_byte=0;
    int is_alg_filename=0;
    int is_source_file=0;
    
    //初始化变量
    memset(algfilename,0,ALG_FILE_NAME_MAX);
    memset(sourcefile,0,ALG_FILE_NAME_MAX);
    

    while ((ch = getopt(argc, argv, "a:s:d:")) != -1){
        printf("optind: %d\n", optind);
        switch (ch) 
        {
            case 'a':
                tmp_alg_byte=atoi(optarg);
                printf("alg byte: %d\n",tmp_alg_byte);
                if((tmp_alg_byte!=0)&&(tmp_alg_byte%4==0)){
                    alg_byte_defalut=tmp_alg_byte;
                }
                printf("alg byte defalut is:%d\n",alg_byte_defalut);
                break;
            case 's':
                printf("source file name: %s\n",optarg);
                is_source_file=1;
                memcpy(sourcefile,optarg,strlen(optarg));   
                break;
            case 'd':
                printf("alg file name: %s\n",optarg);
                is_alg_filename=1;
                memcpy(algfilename,optarg,strlen(optarg));
                break;
            case '?':
                printf("Unknown option: %c\n",(char)optopt);
                break;
        }
    }
    
    if(is_alg_filename==0){
        printf("alg file name is null,agrv is -d\n");
        return -1;
    }
    if(is_source_file==0){
        printf("source file name is null,agrv is -s\n");
        return -1;
    }
    
    //开始执行二进制文件拷贝
    return algintobin(algfilename,sourcefile);

}
